'''
Created on May 18, 2011

@author: Igor
'''

from lib.common_cards import CardDeck, Player, Table, \
        get_combos_with_indicators, cmp_combos

class Decision:
    FOLD=0
    CHECK=1
    CALL=2
    BET=3

_CHALLENGE_MAPPING = {0:"SUPER FISH",
                      1:"FISH"}

def get_challenge_name(level):
    return _CHALLENGE_MAPPING[level]

def get_challenge_level(money):
    if money < 1000:
        return 0
    else:
        return 1

def game_setup(game):
    # Setup the game
    deck = CardDeck()
    my_player = Player()
    table = Table()
    your_player = Player()
    # Deal the cards
    for _ in xrange(2):
        deck.deal_card(my_player)
    for _ in xrange(5):
        deck.deal_card(table)
    for _ in xrange(2):
        deck.deal_card(your_player)
    # Retrieve the cards
    my_cards = my_player.get_cards()
    table_cards = table.get_cards()
    your_cards = your_player.get_cards()
    # Convert the cards from ints to strings for storing
    my_cards_str = [str(i) for i in my_cards]
    table_cards_str = [str(i) for i in table_cards]
    your_cards_str = [str(i) for i in your_cards]
    game.my_cards = my_cards_str
    game.table_cards = table_cards_str
    game.your_cards = your_cards_str
    game.put()

def get_bidding_size(game):
    if game.round == 1:
        return len(game.preflop_bids)
    elif game.round == 2:
        return len(game.flop_bids)
    elif game.round == 3:
        return len(game.turn_bids)
    elif game.round == 4:
        return len(game.river_bids)
    else:
        print "What are we doing getting size in round %d?" % game.round
        raise

def betting_round_finished(game):
    if game.balance != 0:
        return False
    else:
        num_bids = get_bidding_size(game)
        if (num_bids > 3 or 
            game.round > 1 and num_bids > 1):
            return True
        else:
            return False

def add_bid(game, bid):
    if game.round == 1:
        game.preflop_bids.append(bid)
    elif game.round == 2:
        game.flop_bids.append(bid)
    elif game.round == 3:
        game.turn_bids.append(bid)
    elif game.round == 4:
        game.river_bids.append(bid)
    else:
        print "What are we doing adding bids in round %d" % game.round
        raise

def get_last_bid(game):
    if game.round == 1:
        return game.preflop_bids[-1]
    elif game.round == 2:
        return game.flop_bids[-1]
    elif game.round == 3:
        return game.turn_bids[-1]
    elif game.round == 4:
        return game.river_bids[-1]
    else:
        print "What are we doing getting bids in round %d?" % game.round
        raise

def modify_last_bid(game, bid):
    if game.round == 1:
        game.preflop_bids[-1] = bid
    elif game.round == 2:
        game.flop_bids[-1] = bid
    elif game.round == 3:
        game.turn_bids[-1] = bid
    elif game.round == 4:
        game.river_bids[-1] = bid
    else:
        print "What are we doing modifying bids in round %d?" % game.round
        raise

def put_blinds(game):
    small_blind = game.big_blind / 2
    if (game.my_money <= small_blind or game.your_money <= small_blind):
        contribution = min(game.my_money, game.your_money)
        game.pot_money = 2 * contribution
        game.my_money -= contribution
        game.preflop_bids.append(contribution)
        game.your_money -= contribution
        game.preflop_bids.append(contribution)
        game.balance = 0
        game.all_in = True
        game.round_over = True
    elif game.i_deal and game.your_money <= game.big_blind:
        contribution = game.your_money
        game.pot_money = small_blind + contribution
        game.my_money -= small_blind
        game.preflop_bids.append(small_blind)
        game.your_money -= contribution
        game.preflop_bids.append(contribution)
        game.balance = contribution - small_blind
        game.all_in = True
        game.round_over = True
    elif not game.i_deal and game.my_money <= game.big_blind:
        contribution = game.my_money
        game.pot_money = small_blind + contribution
        game.my_money -= contribution
        game.your_money -= small_blind
        game.preflop_bids.append(small_blind)
        game.preflop_bids.append(contribution)
        game.balance = small_blind - contribution
        game.all_in = True
        game.round_over = True
    else:
        game.pot_money = small_blind + game.big_blind
        game.preflop_bids.append(small_blind)
        game.preflop_bids.append(game.big_blind)
        if game.i_deal:
            game.my_money -= small_blind
            game.your_money -= game.big_blind
            game.balance = small_blind
        else:
            game.my_money -= game.big_blind
            game.your_money -= small_blind
            game.balance = small_blind * -1
    game.put()
            
def generate_choices(game):
    if game.balance > 0:
        print "Inconsistent state, should never be greater than 0"
        raise
    choices = [None] * 3
    if game.all_in:
        print "We are not supposed to generate choices for all-in!"
    else:
        choices[0] = "FOLD"
        if game.balance == 0:
            choices[1] = "CHECK"
            choices[2] = "BET"
        else:
            balance = game.balance * -1
            if game.your_money < balance:
                choices[1] = "CALL %d" % game.your_money
                # Lower the last bet to an all-in 
                game.my_money += balance - game.your_money
                modify_last_bid(game, game.your_money)
            else:
                choices[1] = "CALL %d" % balance
                choices[2] = "RAISE"
    return choices

def get_winner(game):
    my_cards_int = [int(i) for i in game.my_cards]
    table_cards_int = [int(i) for i in game.table_cards]
    your_cards_int = [int(i) for i in game.your_cards]
    my_combos = get_combos_with_indicators(my_cards_int + table_cards_int)
    your_combos = get_combos_with_indicators(your_cards_int + table_cards_int)
    return cmp_combos(your_combos, my_combos)

def call_bet(game):
    if game.my_money <= game.balance:
        amt = game.my_money
        game.your_money += game.balance - game.my_money
        game.pot_money -= game.balance - 2 * game.my_money
        modify_last_bid(game, amt)
        add_bid(game, amt)
        game.my_money = 0
        game.balance = 0
        game.all_in = True
    else:
        amt = game.balance
        game.my_money -= game.balance
        game.pot_money += game.balance
        add_bid(game, amt)
        game.balance = 0
        game.round_over = betting_round_finished(game)
        if game.your_money == 0:
            game.all_in = True
    return Decision.CALL